package cn.xuewenbao.ucenter.controller;


import cn.xuewenbao.ucenter.entity.Member;
import cn.xuewenbao.ucenter.entity.ThirdAccount;
import cn.xuewenbao.ucenter.entity.vo.ThirdLoginVo;
import cn.xuewenbao.ucenter.service.MemberService;
import cn.xuewenbao.ucenter.service.ThirdAccountService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xkcoding.justauth.AuthRequestFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mafayu
 * @since 2021-06-15
 */
@RestController
@RequestMapping("/ucenter/thirdaccount")
@Api(tags = "第三方登录2")
@Slf4j
public class ThirdAccountController {

    @Autowired
    private ThirdAccountService accountService;

    @Autowired
    private MemberService memberService;


    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private AuthRequestFactory factory;

    @ApiOperation("生成二维码，重定向")
    @RequestMapping("/render/{source}")
    public void render(@PathVariable("source") String source,
                       HttpServletResponse response) throws IOException {
        log.info("第三方登录进入render：" + source);
        AuthRequest authRequest = factory.get(source);
        String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
        log.info("第三方登录认证地址：" + authorizeUrl);
        response.sendRedirect(authorizeUrl);
    }

    @ApiOperation("获取扫描人信息，添加数据")
    @RequestMapping("/{source}/callback")
    public String loginThird(@PathVariable("source") String source,
                             AuthCallback callback,
                             ModelMap modelMap) {
        log.info("第三方登录进入callback：" + source + " params：" + JSONObject.toJSONString(callback));
        AuthRequest authRequest = factory.get(source);
        AuthResponse response = authRequest.login(callback);
        log.info(JSONObject.toJSONString(response));
        Result<JSONObject> result = new Result<>();

        if (response.getCode() == 2000) {

            JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(response.getData()));
            String username = data.getString("username");
            String avatar = data.getString("avatar");
            String uuid = data.getString("uuid");
            //判断有没有这个人

            QueryWrapper<ThirdAccount> query = new QueryWrapper<>();
            query.eq("third_user_uuid", uuid);
            query.eq("third_type", source);
            List<ThirdAccount> thridList = accountService.list(query);
            ThirdAccount thirdAccount = new ThirdAccount();
            if (thridList == null || thridList.size() == 0) {
                //否则直接创建新账号
                thirdAccount.setRealname(username);
                thirdAccount.setAvatar(avatar);
                thirdAccount.setThirdType(source);
                thirdAccount.setThirdUserUuid(uuid);
                accountService.save(thirdAccount);
            } else {
                //已存在 只设置用户名 不设置头像
                thirdAccount = thridList.get(0);
            }
            // 生成token
            //update-begin-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id，不存在绑定手机号
            if (oConvertUtils.isNotEmpty(thirdAccount.getUserId())) {
                String userId = thirdAccount.getUserId();
                Member member = memberService.getById(userId);
                String token = saveToken(member);
                modelMap.addAttribute("token", token);
            } else {
                //绑定手机号
                modelMap.addAttribute("token", "绑定手机号," + "" + uuid);
            }
            //update-end-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id，不存在绑定手机号
            //update-begin--Author:wangshuai  Date:20200729 for：接口在签名校验失败时返回失败的标识码 issues#1441--------------------
        } else {
            modelMap.addAttribute("token", "登录失败");
        }
        //update-end--Author:wangshuai  Date:20200729 for：接口在签名校验失败时返回失败的标识码 issues#1441--------------------
//        result.setSuccess(false);
//        result.setMessage("第三方登录异常,请联系管理员");
        return "thirdLogin";
    }



    /**
     * 创建新账号
     *
     * @param
     * @return
     */
    @ApiOperation("创建新账号")
    @PostMapping("/user/create")
    @ResponseBody
    public Result<String> thirdUserCreate(@RequestBody ThirdLoginVo model) {
        log.info("第三方登录创建新账号：");
        Result<String> res = new Result<>();
        Object operateCode = redisUtil.get(CommonConstant.THIRD_LOGIN_CODE);
        if (operateCode == null || !operateCode.toString().equals(model.getOperateCode())) {
            res.setSuccess(false);
            res.setMessage("校验失败");
            return res;
        }
        //创建新账号
        //update-begin-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id，在查询用户表尽行token
        ThirdAccount user = saveThirdUser(model);
        if (oConvertUtils.isNotEmpty(user.getUserId())) {
            String sysUserId = user.getUserId();
            Member member = memberService.getById(sysUserId);
            // 生成token
            String token = saveToken(member);
            //update-end-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id，在查询用户表尽行token
            res.setResult(token);
            res.setSuccess(true);
        }
        return res;
    }
    /**
     * 绑定账号 需要设置密码 需要走一遍校验
     * @param json
     * @return
     */
    @ApiOperation("绑定账号 需要设置密码 需要走一遍校验")
    @PostMapping("/user/checkPassword")
    @ResponseBody
    public Result<String> checkPassword(@RequestBody JSONObject json) {
        Result<String> result = new Result<>();
        Object operateCode = redisUtil.get(CommonConstant.THIRD_LOGIN_CODE);
        if(operateCode==null || !operateCode.toString().equals(json.getString("operateCode"))){
            result.setSuccess(false);
            result.setMessage("校验失败");
            return result;
        }
        String username = json.getString("uuid");
        Member user = memberService.getUserByName(username);
        if(user==null){
            result.setMessage("用户未找到");
            result.setSuccess(false);
            return result;
        }

        String password = json.getString("password");
        String salt = user.getSalt();
        String passwordEncode = PasswordUtil.encrypt(user.getMobile(), password, salt);
        if(!passwordEncode.equals(user.getPassword())){
            result.setMessage("密码不正确");
            result.setSuccess(false);
            return result;
        }

        memberService.updateById(user);
        result.setSuccess(true);
        // 生成token
        String token = saveToken(user);
        result.setResult(token);
        return result;
    }

    private ThirdAccount saveThirdUser(ThirdLoginVo model) {
        ThirdAccount thirdAccount = new ThirdAccount();
        //否则直接创建新账号
        thirdAccount.setRealname(model.getRealname());
        thirdAccount.setAvatar(model.getAvatar());
        thirdAccount.setThirdType(model.getThirdType());
        thirdAccount.setThirdUserUuid(model.getThirdUserUuid());
        accountService.save(thirdAccount);
        return thirdAccount;
    }

    private String saveToken(Member member) {
        // 生成token
        String token = JwtUtil.sign(member.getMobile(), member.getPassword());
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        // 设置超时时间
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);
        return token;
    }

    /**
     * 第三方绑定手机号返回token
     *
     * @param jsonObject
     * @return
     */
    @ApiOperation("绑定手机号")
    @PostMapping("/bindingThirdPhone")
    @ResponseBody
    public Result<String> bindingThirdPhone(@RequestBody JSONObject jsonObject) {
        Result<String> result = new Result<String>();
        String phone = jsonObject.getString("mobile");
        String thirdUserUuid = jsonObject.getString("thirdUserUuid");
        //校验用户有效性
        Member member = memberService.getUserByPhone(phone);
        if(member != null){
            accountService.updateThirdUserId(member,thirdUserUuid);
        }else{
            // 不存在手机号，创建用户
            String smscode = jsonObject.getString("captcha");
            Object code = redisUtil.get(phone);
            if (!smscode.equals(code)) {
                result.setMessage("手机验证码错误");
                result.setSuccess(false);
                return result;
            }
            //创建用户
            member = accountService.createUser(phone,thirdUserUuid);
        }
        String token = saveToken(member);
        result.setSuccess(true);
        result.setResult(token);
        return result;
    }
//    /**
//     * 用户注册接口
//     *
//     * @param jsonObject
//     * @param user
//     * @return
//     */
//    @PostMapping("/register")
//    public Result<JSONObject> userRegister(@RequestBody JSONObject jsonObject, SysUser user) {
//        Result<JSONObject> result = new Result<JSONObject>();
//        String phone = jsonObject.getString("phone");
//        String smscode = jsonObject.getString("smscode");
//        Object code = redisUtil.get(phone);
//        String username = jsonObject.getString("username");
//        //未设置用户名，则用手机号作为用户名
//        if(oConvertUtils.isEmpty(username)){
//            username = phone;
//        }
//        //未设置密码，则随机生成一个密码
//        String password = jsonObject.getString("password");
//        if(oConvertUtils.isEmpty(password)){
//            password = RandomUtil.randomString(8);
//        }
//        String email = jsonObject.getString("email");
//        SysUser sysUser1 = sysUserService.getUserByName(username);
//        if (sysUser1 != null) {
//            result.setMessage("用户名已注册");
//            result.setSuccess(false);
//            return result;
//        }
//        SysUser sysUser2 = sysUserService.getUserByPhone(phone);
//        if (sysUser2 != null) {
//            result.setMessage("该手机号已注册");
//            result.setSuccess(false);
//            return result;
//        }
//
//        if(oConvertUtils.isNotEmpty(email)){
//            SysUser sysUser3 = sysUserService.getUserByEmail(email);
//            if (sysUser3 != null) {
//                result.setMessage("邮箱已被注册");
//                result.setSuccess(false);
//                return result;
//            }
//        }
//        if(null == code){
//            result.setMessage("手机验证码失效，请重新获取");
//            result.setSuccess(false);
//            return result;
//        }
//        if (!smscode.equals(code.toString())) {
//            result.setMessage("手机验证码错误");
//            result.setSuccess(false);
//            return result;
//        }
//
//        try {
//            user.setCreateTime(new Date());// 设置创建时间
//            String salt = oConvertUtils.randomGen(8);
//            String passwordEncode = PasswordUtil.encrypt(username, password, salt);
//            user.setSalt(salt);
//            user.setUsername(username);
//            user.setRealname(username);
//            user.setPassword(passwordEncode);
//            user.setEmail(email);
//            user.setPhone(phone);
//            user.setStatus(CommonConstant.USER_UNFREEZE);
//            user.setDelFlag(CommonConstant.DEL_FLAG_0);
//            user.setActivitiSync(CommonConstant.ACT_SYNC_0);
//            sysUserService.addUserWithRole(user,"ee8626f80f7c2619917b6236f3a7f02b");//默认临时角色 test
//            result.success("注册成功");
//        } catch (Exception e) {
//            result.error500("注册失败");
//        }
//        return result;
//    }
}

